import datetime
import random
import json
import os
import time
import uuid
from string import ascii_letters, digits
from rest_framework import serializers
from wechatpayv3 import WeChatPayType
from apps.orders.models import Order
from apps.utils.helper.wx_pay_helper import WxPayHelper


class PaymentSerializer(serializers.Serializer):

    amount = serializers.DecimalField(max_digits=10, decimal_places=2, write_only=True, help_text='支付金额')

    def create(self, validated_data):
        user = getattr(self.context['request'], 'current_user', None)
        original_amount = validated_data.pop('amount')
        out_trade_no = ''.join(random.choice(ascii_letters + digits) for _ in range(8))
        description = '红包挑战红包'
        amount = int(float(original_amount) * (1 - 0.02) * 100)

        wx_pay_instance = WxPayHelper().get_wx_pay_instance()
        code, message = wx_pay_instance.pay(
            description=description,
            out_trade_no=out_trade_no,
            amount={'total': amount},
            pay_type=WeChatPayType.JSAPI,
            payer={
                'openid': user.wei_chat_open_id,
            },
        )
        result = json.loads(message)
        if code not in [200, 300]:
            raise serializers.ValidationError('支付失败')

        prepay_id = result.get('prepay_id')

        Order.objects.create(
            prepay_id=prepay_id,
            out_trade_no=out_trade_no,
            pay_time=datetime.datetime.now(),
        )

        timestamp = str(int(time.time()))
        noncestr = str(uuid.uuid4()).replace('-', '')
        package = 'prepay_id=' + prepay_id
        sign = wx_pay_instance.sign([os.environ.get('WX_APPID'), timestamp, noncestr, package])
        signtype = 'RSA'

        data = {
            "appId": os.environ.get('WX_APPID'),
            "timeStamp": timestamp,
            "nonceStr": noncestr,
            "package": package,
            "signType": signtype,
            "paySign": sign,
            "out_trade_no": out_trade_no
        }

        return data
